<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			/*事件就是用户或浏览器自身执行的某种动作。诸如 click、load 和 mouseover，都是事件的名字。
                         而响应某个事件的函数就叫做事件处理程序（或事件侦听器）。*/
                        
            //13.2.1 HTML事件处理程序
                 //某个元素支持的每种事件，都可以使用一个与相应事件处理程序同名的 HTML 特性来指定。
                      <input type="button" value="Click Me" onclick="alert('Clicked')"/> 
                 //在 HTML中指定事件处理程序有三个缺点
	                 //1.存在一个时差问题。因为用户可能会在HTML元素一出现在页面上就触发相应的事件，但当时的事件处理程序有可能尚不具备执行条件
	                 //2.这样扩展事件处理程序的作用域链在不同浏览器中会导致不同结果。不同 JavaScript引擎遵循的标识符解析规则略有差异，很可能会在访问非限定对象成员时出错。
	                 //3.HTML与JavaScript代码紧密耦合
	                 
	         //13.2.2 DOM0级事件处理程序
	             //通过 JavaScript 指定事件处理程序的传统方式，就是将一个函数赋值给一个事件处理程序属性。
	                    var btn = document.getElementById("myBtn"); 
						btn.onclick = function(){ 
						  alert("Clicked"); 
						}; 
                 //删除通过 DOM0 级方法指定的事件处理程序，将事件处理程序属性的值设置为 null即可
                        btn.onclick = null; //删除事件处理程序

            //13.2.3 DOM2级事件处理程序
                //DOM2级事件定义了两个方法，用于处理指定和删除事件处理程序的操作：addEventListener()和 removeEventListener()。
                	//接受 3 个参数：要处理的事件名、作为事件处理程序的函数和一个布尔值。
                	//最后这个布尔值参数如果是 true，表示在捕获阶段调用事件处理程序
                	//如果是 false，表示在冒泡阶段调用事件处理程序
                	    var btn = document.getElementById("myBtn");
                	    btn.addEventListener('click',function(){
                	    	console.log(this.id)
                	    },false)
                //使用 DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。
                        var btn = document.getElementById("myBtn");
                	    btn.addEventListener('click',function(){
                	    	console.log(this.id);
                	    },false)
                	    btn.addEventListener('click',function(){
                	    	console.log(this);
                	    },false)
                //通过 addEventListener()添加的事件处理程序只能removeEventListener()来移除。移除时传入的参数与添加处理程序时使用的参数相同。
                //通过 addEventListener()添加的匿名函数将无法移除。
                        var btn = document.getElementById("myBtn");
                	    btn.addEventListener('click',function(){
                	    	console.log(this.id);
                	    },false);
                	    btn.removeEventListener('click',function(){
                	    	console.log(this.id);
                	    },false);//没有用，无法移除click事件，因为两次传入的参数看似相同，但两次传入的函数实际上不是同一个(如下例所示)
                	    
                  	    //两次传入的函数不是同一个
                	    var a = function(){
							alert('div');
						}
						var b = function(){
							alert('div');
						}
						console.log(a === b);//false
                	    //两次传入的函数不是同一个
                	    
                	    
                	    var btn = document.getElementById("myBtn");
                	    var handler = function(){
                	    	console.log(this.id);
                	    }
                	    btn.addEventListener('click',handler,false);
                	    btn.removeListener('click',handler,false);//有效，可以移除click事件
                	    
                //大多数情况下，都是将事件处理程序添加到事件流的冒泡阶段，这样可以最大限度地兼容各种浏览器。	    
                //最好只在需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。如果不是特别需要，我们不建议在事件捕获阶段注册事件处理程序。
                
            //13.2.4 IE事件处理程序
                //IE实现了与 DOM中类似的两个方法：attachEvent()和 detachEvent()。
                //这两个方法接受相同的两个参数：事件处理程序名称与事件处理程序函数。
                
                // 在 IE 中使用 attachEvent()与使用 DOM0 级方法的主要区别在于事件处理程序的作用域。
                // 在使用 DOM0 级方法的情况下，事件处理程序会在其所属元素的作用域内运行；
                // 在使用 attachEvent()方法的情况下，事件处理程序会在全局作用域中运行，因此 this 等于 window。
                
                //attachEvent()方法也可以用来为一个元素添加多个事件处理程序。不过与DOM方法不同的是，这些事件处理程序
                //不是以添加它们的顺序执行，而是以相反的顺序被触发
                            var btn = document.getElementById("myBtn"); 
							btn.attachEvent("onclick", function(){ 
							   alert("Clicked"); //后弹出
							}); 
							btn.attachEvent("onclick", function(){ 
							   alert("Hello world!");//先弹出
							}); 
				//使用 attachEvent()添加的事件可以通过 detachEvent()来移除，条件是必须提供相同的参数。
				//与 DOM 方法一样，这也意味着添加的匿名函数将不能被移除。
				
		    //13.2.5 跨浏览器的事件处理程序
		            var EventUtil = {
						addHandler:function(element,type,handler){
							if(element.addEventListener){
							   element.addEventListener(type,handler,false);
							}else if(element.attachEvent){
							   element.attachEvent('on' + type,handler);
							}else{
								element['on' + type] = handler;
							}
						},
						removeHandler:function(element,type,handler){
							if(element.removeEventListener){
								element.removeEventListener(type,handler,false);
							}else if(element.detachEvent){
								element.detachEvent('on' + type,handler);
							}else{
								element['on' + type] = null;
							}
						}
					}
		</script>
	</body>
</html>
